package cn.shujuhai.workflow.service.flow;

import cn.dev33.satoken.stp.StpUtil;
import cn.shujuhai.common.mapper.SysUserMapper;
import cn.shujuhai.common.pluging.data.ResultVo;
import cn.shujuhai.workflow.domain.ActDepartment;
import cn.shujuhai.workflow.domain.Form;
import cn.shujuhai.workflow.domain.FormData;
import cn.shujuhai.workflow.service.ActDepartmentService;
import cn.shujuhai.workflow.service.FormDataService;
import cn.shujuhai.workflow.service.FormService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.github.pagehelper.PageInfo;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.common.engine.impl.util.IoUtil;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.repository.ProcessDefinitionQuery;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.RequestBody;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Author: ZhangDeZhong
 * @Date: 2025/3/19 11:13
 * @Description:
 **/
@Service
@RequiredArgsConstructor
public class FlowableService {
    private final RepositoryService repositoryService;
    private final IdentityService identityService;
    private final RuntimeService runtimeService;
    private final TaskService taskService;
    private final HistoryService historyService;
    private final ProcessEngine processEngine;
    private final FormDataService formDataService;
    private final FormService formService;
    private final ActDepartmentService actDepartmentService;
    private final SysUserMapper sysUserMapper;
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public ResultVo<?> getProcessList(Long departmentId) {
        // 当前登录用户角色
        List<String> roleCodes = this.sysUserMapper.selectRoleCodesByUserId(StpUtil.getLoginIdAsLong());

        // 构造查询
        ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery()
                .orderByDeploymentId().desc();

        // 非 super_admin：按部门过滤
        if (!roleCodes.contains("super_admin")) {
            // 直接查 act_department 表得到 deploymentId 集合
            List<String> deploymentIds = this.actDepartmentService.list(
                            new QueryWrapper<ActDepartment>()
                                    .eq("department_id", departmentId))
                    .stream()
                    .map(ActDepartment::getId)
                    .collect(Collectors.toList());

            if (CollectionUtils.isEmpty(deploymentIds)) {
                PageInfo<Map<String, Object>> empty = new PageInfo<>(Collections.emptyList());
                empty.setTotal(0L);
                return ResultVo.success(empty);
            }
            query.deploymentIds(new HashSet<>(deploymentIds));
        }

        // 取流程定义并转 Map
        List<ProcessDefinition> list = query.list();
        List<Map<String, Object>> listMap = new ArrayList<>();
        for (ProcessDefinition pd : list) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", pd.getId());
            map.put("name", pd.getName());
            map.put("key", pd.getKey());
            map.put("version", pd.getVersion());
            map.put("deploymentId", pd.getDeploymentId());
            map.put("resourceName", pd.getResourceName());
            map.put("diagramResourceName", pd.getDiagramResourceName());
            map.put("suspensionState", pd.isSuspended() ? "SUSPENDED" : "ACTIVE");
            map.put("isSuspended", pd.isSuspended());
            listMap.add(map);
        }

        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(listMap);
        pageInfo.setTotal(query.count());
        return ResultVo.success(pageInfo);
    }

    public ResultVo<?> getProcessDiagram(String processDefinitionId) {
        // 获取默认的 ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();

        // 获取流程图的 InputStream
        InputStream processDiagramStream = repositoryService.getProcessDiagram(processDefinitionId);

        if (processDiagramStream != null) {
            try {
                // 将 InputStream 转换为 byte 数组
                byte[] buffer = new byte[processDiagramStream.available()];
                processDiagramStream.read(buffer);
                return ResultVo.success(buffer);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    processDiagramStream.close(); // 确保关闭流
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return ResultVo.success(new byte[0]);
    }


    @Transactional(rollbackFor = Exception.class)
    public ResultVo<?> saveBpmn(@RequestBody Map<String, Object> data) {
        // 1. 基本参数
        String bpmnXml = (String) data.get("bpmnXml");
        String name = (String) data.get("name");

        // 2. 解析部门 id（单个字符串 或 字符串列表）
        Object deptObj = data.get("deptId");
        List<String> deptIds = new ArrayList<>();
        if (deptObj instanceof String) {
            deptIds.add((String) deptObj);
        } else if (deptObj instanceof List) {
            deptIds.addAll((List<String>) deptObj);
        }
        if (deptIds.isEmpty()) {
            return ResultVo.failure("请选择部门");
        }

        try {
            // 3. 部署流程
            Deployment deployment = repositoryService.createDeployment()
                    .addString("process.bpmn20.xml", bpmnXml)
                    .name(name)
                    .deploy();
            String deploymentId = deployment.getId();

            // 4. 批量写入中间表 act_department
            List<ActDepartment> list = deptIds.stream()
                    .map(deptId -> {
                        ActDepartment ad = new ActDepartment();
                        ad.setId(deploymentId);          // 对应流程部署 ID
                        ad.setDepartmentId(Long.valueOf(deptId)); // 对应部门 id
                        return ad;
                    })
                    .collect(Collectors.toList());
            this.actDepartmentService.saveBatch(list);

            return ResultVo.success("流程已成功部署，部署 ID: " + deploymentId);
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResultVo.failure("流程部署失败: " + e.getMessage());
        }
    }


    public ResultVo<?> deployProcess(String bpmnFileName) {
        try {
            // 从类路径加载 BPMN 文件
            InputStream bpmnInputStream = this.getClass().getClassLoader().getResourceAsStream("processes/" + bpmnFileName);
            if (bpmnInputStream == null) {
                return ResultVo.failure("BPMN 文件未找到");
            }
            Deployment deployment = repositoryService.createDeployment()
                    .addInputStream(bpmnFileName, bpmnInputStream)
                    .deploy();
            return ResultVo.success("流程部署成功" + deployment.getId());
        } catch (Exception e) {
            return ResultVo.failure("流程部署失败：" + e.getMessage());
        }
    }

    public String startProcess(String processDefinitionId) {
        // 创建流程变量

        // 启动流程实例
        identityService.setAuthenticatedUserId(StpUtil.getLoginIdAsString());
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId);

        return processInstance.getId();
    }

    public ResultVo<?> getProcessInstanceList(int pageNum, int pageSize) {

        // 1. 构造查询器
        ProcessInstanceQuery query = runtimeService
                .createProcessInstanceQuery()
                .orderByProcessInstanceId()
                .asc();

        // 2. 非管理员：只查自己发起的流程
        if (StpUtil.getLoginIdAsLong() != 1) {
            List<FormData> formDataList = formDataService.list(
                    Wrappers.<FormData>lambdaQuery()
                            .eq(FormData::getSubmitUserId, StpUtil.getLoginIdAsLong())
            );
            if (formDataList.isEmpty()) {
                return ResultVo.success(new PageInfo<>());
            }
            Set<String> ids = formDataList.stream()
                    .map(FormData::getProcessInstanceId)
                    .collect(Collectors.toSet());
            query.processInstanceIds(ids);
        }

        // 3. 总记录数（已按用户过滤）
        long total = query.count();

        // 4. 分页查询（与 total 使用同一查询器）
        List<ProcessInstance> list = query
                .listPage((pageNum - 1) * pageSize, pageSize);

        // 5. 转 Map
        List<Map<String, Object>> listMap = new ArrayList<>();
        for (ProcessInstance p : list) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", p.getId());
            map.put("processDefinitionId", p.getProcessDefinitionId());
            map.put("businessKey", p.getBusinessKey());
            map.put("processDefinitionKey", p.getProcessDefinitionKey());
            map.put("processDefinitionName", p.getProcessDefinitionName());
            map.put("processDefinitionVersion", p.getProcessDefinitionVersion());
            map.put("activityId", p.getActivityId());
            map.put("startUserId", p.getStartUserId());
            map.put("suspended", p.isSuspended());
            map.put("startTime", formatter.format(p.getStartTime()));
            listMap.add(map);
        }

        // 6. 封装分页结果
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(listMap);
        pageInfo.setTotal(total);

        return ResultVo.success(pageInfo);
    }

    public ResultVo<?> getHistoryProcessInstanceList(int pageNum, int pageSize) {
        // 1. 构造查询器
        HistoricProcessInstanceQuery query = historyService
                .createHistoricProcessInstanceQuery()
                .orderByProcessInstanceStartTime()
                .desc();

        // 2. 非管理员：只查自己发起的流程
        if (StpUtil.getLoginIdAsLong() != 1) {
            // 2.1 先查当前用户提交过的 form_data，拿到流程实例ID
            List<FormData> formDataList = formDataService.list(
                    Wrappers.<FormData>lambdaQuery()
                            .eq(FormData::getSubmitUserId, StpUtil.getLoginIdAsLong())
            );
            if (formDataList.isEmpty()) {
                return ResultVo.success(new PageInfo<>());
            }
            // 2.2 把流程实例ID转成 Set 并设置到查询器
            Set<String> ids = formDataList.stream()
                    .map(FormData::getProcessInstanceId)
                    .collect(Collectors.toSet());
            query.processInstanceIds(ids);
        }

        // 3. 统计总记录数（已按用户过滤）
        long total = query.count();

        // 4. 分页查询
        List<HistoricProcessInstance> list = query
                .listPage((pageNum - 1) * pageSize, pageSize);

        // 5. 转 Map
        List<Map<String, Object>> listMap = new ArrayList<>();
        for (HistoricProcessInstance p : list) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", p.getId());
            map.put("processDefinitionId", p.getProcessDefinitionId());
            map.put("businessKey", p.getBusinessKey());
            map.put("processDefinitionKey", p.getProcessDefinitionKey());
            map.put("processDefinitionName", p.getProcessDefinitionName());
            map.put("processDefinitionVersion", p.getProcessDefinitionVersion());
            map.put("startUserId", p.getStartUserId());
            map.put("startActivityId", p.getStartActivityId());
            map.put("endActivityId", p.getEndActivityId());
            map.put("deleteReason", p.getDeleteReason());
            map.put("startTime", p.getStartTime() == null ? "" : formatter.format(p.getStartTime()));
            map.put("endTime", p.getEndTime() == null ? "" : formatter.format(p.getEndTime()));
            listMap.add(map);
        }

        // 6. 封装 PageInfo
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(listMap);
        pageInfo.setTotal(total);

        return ResultVo.success(pageInfo);
    }

    public ResultVo<?> getTasks(String processInstanceId) {
        List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstanceId).list();
        List<Map<String, Object>> listMap = new ArrayList<>();

        for (Task t : tasks) {
            Map<String, Object> map = new HashMap<>();
            // 提取 Task 的属性并存入 map
            map.put("id", t.getId()); // 任务 ID
            map.put("processInstanceId", t.getProcessInstanceId()); // 流程实例 ID
            map.put("processDefinitionId", t.getProcessDefinitionId()); // 流程定义 ID
            map.put("executionId", t.getExecutionId()); // 执行实例 ID
            map.put("name", t.getName()); // 任务名称
            map.put("assignee", t.getAssignee()); // 任务分配人
            map.put("owner", t.getOwner()); // 任务所有者
            map.put("createTime", formatter.format(t.getCreateTime())); // 任务创建时间
            map.put("dueDate", t.getDueDate()); // 任务截止日期
            map.put("priority", t.getPriority()); // 任务优先级
            map.put("suspended", t.isSuspended()); // 是否挂起
            map.put("taskDefinitionKey", t.getTaskDefinitionKey()); // 任务定义 Key
            // 添加到最终的列表中
            listMap.add(map);
        }
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(listMap);
        pageInfo.setTotal(this.taskService.createTaskQuery().count());
        return ResultVo.success(pageInfo);
    }


    public ResultVo<?> getTaskList() {
        String assignee = StpUtil.getLoginIdAsString();

        List<Task> tasks = taskService.createTaskQuery().taskAssignee(assignee).list();
        List<Map<String, Object>> listMap = new ArrayList<>();

        for (Task t : tasks) {
            Map<String, Object> map = new HashMap<>();
            // 提取 Task 的属性并存入 map
            map.put("id", t.getId()); // 任务 ID
            map.put("processInstanceId", t.getProcessInstanceId()); // 流程实例 ID
            map.put("processDefinitionId", t.getProcessDefinitionId()); // 流程定义 ID
            map.put("executionId", t.getExecutionId()); // 执行实例 ID
            map.put("name", t.getName()); // 任务名称
            map.put("assignee", t.getAssignee()); // 任务分配人
            map.put("owner", t.getOwner()); // 任务所有者
            map.put("formKey", t.getFormKey()); // 任务表单
            map.put("parentTaskId", t.getParentTaskId());
            map.put("createTime", formatter.format(t.getCreateTime())); // 任务创建时间
            map.put("dueDate", t.getDueDate()); // 任务截止日期
            map.put("priority", t.getPriority()); // 任务优先级
            map.put("suspended", t.isSuspended()); // 是否挂起
            map.put("taskDefinitionKey", t.getTaskDefinitionKey()); // 任务定义 Key
            // 添加到最终的列表中
            listMap.add(map);
        }
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(listMap);
        pageInfo.setTotal(this.taskService.createTaskQuery().count());
        return ResultVo.success(pageInfo);
    }

    public ResultVo<?> getTaskFinishList() {
        String assignee = StpUtil.getLoginIdAsString();
        // 查询已办任务
        HistoricTaskInstanceQuery historicTaskInstanceQuery = historyService.createHistoricTaskInstanceQuery();
        historicTaskInstanceQuery.taskAssignee(assignee); // 指定办理人
        historicTaskInstanceQuery.finished(); // 只查询已完成的任务

        List<HistoricTaskInstance> historicTaskInstances = historicTaskInstanceQuery.list();
        List<Map<String, Object>> listMap = new ArrayList<>();

        for (HistoricTaskInstance t : historicTaskInstances) {
            Map<String, Object> map = new HashMap<>();
            map.put("id", t.getId());
            map.put("name", t.getName());
            map.put("description", t.getDescription());
            map.put("assignee", t.getAssignee());
            map.put("owner", t.getOwner());
            map.put("createTime", formatter.format(t.getCreateTime()));
            map.put("endTime", formatter.format(t.getEndTime()));
            map.put("durationInMillis", t.getDurationInMillis());
            map.put("processInstanceId", t.getProcessInstanceId());
            map.put("processDefinitionId", t.getProcessDefinitionId());
            map.put("deleteReason", t.getDeleteReason());
            map.put("taskDefinitionKey", t.getTaskDefinitionKey());
            map.put("parentTaskId", t.getParentTaskId());
            map.put("executionId", t.getExecutionId());
            map.put("priority", t.getPriority());
            // 添加到最终的列表中
            listMap.add(map);
        }
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(listMap);
        pageInfo.setTotal(this.taskService.createTaskQuery().count());
        return ResultVo.success(pageInfo);
    }

    public void processDiagram(String processInstanceId, HttpServletResponse response) throws IOException {
        // 获取流程实例
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
        String processDefinitionId;
        List<String> highLightedActivities = new ArrayList<>();
        List<String> highLightedFlows = new ArrayList<>();

        if (processInstance != null) {
            // 如果流程正在运行，获取当前活动节点
            processDefinitionId = processInstance.getProcessDefinitionId();
            highLightedActivities = runtimeService.getActiveActivityIds(processInstanceId);
        } else {
            // 如果流程已经结束，获取历史节点
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            processDefinitionId = historicProcessInstance.getProcessDefinitionId();

            List<HistoricActivityInstance> historicActivityInstances = historyService.createHistoricActivityInstanceQuery()
                    .processInstanceId(processInstanceId)
                    .orderByHistoricActivityInstanceStartTime()
                    .asc()
                    .list();

            for (HistoricActivityInstance activityInstance : historicActivityInstances) {
                if ("sequenceFlow".equals(activityInstance.getActivityType())) {
                    highLightedFlows.add(activityInstance.getActivityId());
                } else {
                    highLightedActivities.add(activityInstance.getActivityId());
                }
            }
        }

        // 获取 BPMN 模型和流程图生成器
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        ProcessEngineConfiguration engConf = processEngine.getProcessEngineConfiguration();
        ProcessDiagramGenerator diagramGenerator = engConf.getProcessDiagramGenerator();

        // 生成流程图
        InputStream in = diagramGenerator.generateDiagram(bpmnModel, "png", highLightedActivities, highLightedFlows,
                engConf.getActivityFontName(), engConf.getLabelFontName(), engConf.getAnnotationFontName(),
                engConf.getClassLoader(), 1.0, true);

        // 输出到 HTTP 响应
        byte[] buf = new byte[1024];
        int length;
        OutputStream out = response.getOutputStream();
        while ((length = in.read(buf)) != -1) {
            out.write(buf, 0, length);
        }
        IoUtil.closeSilently(out);
        IoUtil.closeSilently(in);
    }

    /**
     * 删除流程定义
     *
     * @param deploymentId 流程定义的 部署Id
     * @param cascade      是否级联删除
     */
    public ResultVo<?> deleteProcessDefinition(String deploymentId, boolean cascade) {
        this.actDepartmentService.remove(new QueryWrapper<ActDepartment>().lambda().eq(ActDepartment::getId, deploymentId));
        repositoryService.deleteDeployment(deploymentId, cascade);
        return ResultVo.success();
    }


    public ResultVo<?> getFormDataByProcessInstanceId(String processInstanceId) throws JsonProcessingException {
        var wrapper = new MPJLambdaWrapper<FormData>();
        wrapper.selectAll(FormData.class)
                .select(Form::getFormName)
                .select(Form::getFieldData)
                .eq(FormData::getProcessInstanceId, processInstanceId)
                .leftJoin(Form.class, Form::getFormId, FormData::getFormId);
        FormData formData = this.formDataService.list(wrapper).stream().findFirst().orElse(null);
        Task currentTask = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)
                .singleResult();
        FormData formData1 = new FormData();
        if (currentTask != null) {
            String formKey = currentTask.getFormKey();
            Form form = this.formService.getById(Long.parseLong(formKey));
            formData1.setFieldData(form.getFieldData());
            formData1.setFormId(form.getFormId());
        }
        List<String> parentTaskIds = new ArrayList<>();
        List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery()
                .processInstanceId(processInstanceId).finished()
                .list();
        for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
            parentTaskIds.add(historicTaskInstance.getId());
        }
        List<FormData> formDataList = new ArrayList<>();
        for (String parentTaskId : parentTaskIds) {
            var wrapper1 = new MPJLambdaWrapper<FormData>();
            wrapper1.selectAll(FormData.class)
                    .select(Form::getFormName)
                    .select(Form::getFieldData)
                    .leftJoin(Form.class, Form::getFormId, FormData::getFormId)
                    .eq(FormData::getTaskId, parentTaskId);
            FormData formData11 = this.formDataService.list(wrapper1).stream().findFirst().orElse(null);
            formDataList.add(formData11);
        }
        // 创建 ObjectMapper 实例
        ObjectMapper objectMapper = new ObjectMapper();

        // 遍历 formDataList，合并 fieldData
        for (FormData data : formDataList) {
            if (data.getFieldData() != null) {
                // 将字符串解析为 JSON 数组
                ArrayNode arrayNode = objectMapper.readValue(data.getFieldData().toString(), ArrayNode.class);
                if (formData.getFieldData() == null) {
                    formData.setFieldData(arrayNode);
                } else {
                    // 将当前 formData 的 fieldData 转换为 ArrayNode
                    ArrayNode currentArrayNode = objectMapper.readValue(formData.getFieldData().toString(), ArrayNode.class);
                    // 合并两个数组
                    currentArrayNode.addAll(arrayNode);
                    formData.setFieldData(objectMapper.writeValueAsString(currentArrayNode));
                }
            }
        }

        Map<String, Object> formDataMap = new HashMap<>();
        formDataMap.put("formData", formData);
        formDataMap.put("formData1", formData1);
        formDataMap.put("formDataList", formDataList);

        return ResultVo.success(formDataMap);
    }


    public ResultVo<?> getProcessInstanceLists(int pageNum, int pageSize) {
        // 1. 获取登录用户ID
        Long loginUserId = StpUtil.getLoginIdAsLong();

        // 2. 查询当前用户提交过的 form_data，拿到流程实例ID
        List<FormData> formDataList = formDataService.list(
                new LambdaQueryWrapper<FormData>()
                        .eq(FormData::getSubmitUserId, loginUserId)
        );

        // 3. 如果用户没有提交过任何流程实例，直接返回空的分页结果
        if (formDataList.isEmpty()) {
            return ResultVo.success(new PageInfo<>());
        }

        // 4. 把流程实例ID转成 Set
        Set<String> processInstanceIds = formDataList.stream()
                .map(FormData::getProcessInstanceId)
                .collect(Collectors.toSet());

        // 5. 构造查询器并设置流程实例ID
        HistoricProcessInstanceQuery query = historyService
                .createHistoricProcessInstanceQuery()
                .processInstanceIds(processInstanceIds)
                .unfinished() // 只查询尚未结束的流程实例
                .orderByProcessInstanceStartTime()
                .desc();

        // 6. 分页查询
        int startRow = (pageNum - 1) * pageSize;
        List<HistoricProcessInstance> list = query.listPage(startRow, pageSize);

        // 7. 统计总记录数
        long total = query.count();

        // 8. 转换为 Map
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<Map<String, Object>> listMap = list.stream().map(p -> {
            Map<String, Object> map = new HashMap<>();
            map.put("id", p.getId());
            map.put("processDefinitionId", p.getProcessDefinitionId());
            map.put("businessKey", p.getBusinessKey());
            map.put("processDefinitionKey", p.getProcessDefinitionKey());
            map.put("processDefinitionName", p.getProcessDefinitionName());
            map.put("processDefinitionVersion", p.getProcessDefinitionVersion());
            map.put("startUserId", p.getStartUserId());
            map.put("startActivityId", p.getStartActivityId());
            map.put("endActivityId", p.getEndActivityId());
            map.put("deleteReason", p.getDeleteReason());
            map.put("startTime", p.getStartTime() == null ? "" : formatter.format(p.getStartTime()));
            map.put("endTime", p.getEndTime() == null ? "" : formatter.format(p.getEndTime()));
            return map;
        }).collect(Collectors.toList());

        // 9. 封装 PageInfo
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(listMap);
        pageInfo.setTotal(total);

        return ResultVo.success(pageInfo);
    }

    public ResultVo<?> getHistoryProcessInstanceLists(int pageNum, int pageSize) {
        // 1. 获取当前登录用户ID
        Long loginUserId = StpUtil.getLoginIdAsLong();

        // 2. 查询当前用户提交过的 form_data，拿到流程实例ID
        List<FormData> formDataList = formDataService.list(
                new LambdaQueryWrapper<FormData>()
                        .eq(FormData::getSubmitUserId, loginUserId)
        );
        System.out.println("++++++++" + formDataList);

        // 3. 如果用户没有提交过任何流程实例，直接返回空的分页结果
        if (formDataList.isEmpty()) {
            return ResultVo.success(new PageInfo<>());
        }

        // 4. 把流程实例ID转成 Set
        Set<String> processInstanceIds = formDataList.stream()
                .map(FormData::getProcessInstanceId)
                .collect(Collectors.toSet());

        // 5. 构造查询器并设置流程实例ID
        HistoricProcessInstanceQuery query = historyService
                .createHistoricProcessInstanceQuery()
                .processInstanceIds(processInstanceIds)
                .finished() // 只查询已经完成的流程实例
                .orderByProcessInstanceStartTime()
                .desc();

        // 6. 分页查询
        int startRow = (pageNum - 1) * pageSize;
        List<HistoricProcessInstance> list = query.listPage(startRow, pageSize);

        // 7. 统计总记录数
        long total = query.count();

        // 8. 转换为 Map
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<Map<String, Object>> listMap = list.stream().map(p -> {
            Map<String, Object> map = new HashMap<>();
            map.put("id", p.getId());
            map.put("processDefinitionId", p.getProcessDefinitionId());
            map.put("businessKey", p.getBusinessKey());
            map.put("processDefinitionKey", p.getProcessDefinitionKey());
            map.put("processDefinitionName", p.getProcessDefinitionName());
            map.put("processDefinitionVersion", p.getProcessDefinitionVersion());
            map.put("startUserId", p.getStartUserId());
            map.put("startActivityId", p.getStartActivityId());
            map.put("endActivityId", p.getEndActivityId());
            map.put("deleteReason", p.getDeleteReason());
            map.put("startTime", p.getStartTime() == null ? "" : formatter.format(p.getStartTime()));
            map.put("endTime", p.getEndTime() == null ? "" : formatter.format(p.getEndTime()));
            return map;
        }).collect(Collectors.toList());

        // 9. 封装 PageInfo
        PageInfo<Map<String, Object>> pageInfo = new PageInfo<>(listMap);
        pageInfo.setTotal(total);

        return ResultVo.success(pageInfo);
    }

}
